iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0

今天我想延續第九天學過的RecyclerView,那時只是一個最基本的應用。,RecyclerView 還有許多進階的應用場景,例如:

  1. 項目點擊事件:當使用者點擊列表中的某個項目時,我們需要能做出反應。
  2. 多種項目類型:如果一個列表頁面需要顯示多種不同樣式的內容(例如:新聞列表同時顯示「文章」和「廣告」)。

今天,我們就要來解決這兩個問題。

一、處理 RecyclerView 項目點擊事件

  • 簡單比喻: 這就像是為列表中的每個項目,都安裝一個 「開關」
    • 當使用者點擊一個項目時,這個「開關」就會被觸發,告訴 App:「有人點擊了這個位置的項目!」

我們會在 Adapter 裡新增一個「監聽器」介面,並讓 MainActivity 來實現這個介面,這樣就能在 MainActivity 中處理點擊事件。

實作步驟:

  1. YourAdapter.java 中新增介面:

    在你的 Adapter 類別裡,新增一個 interface

    `// 在 Adapter 類別裡面
    public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
        // 定義一個介面,用來處理點擊事件
        public interface OnItemClickListener {
            void onItemClick(int position);
        }
    
        private OnItemClickListener listener;
    
        // 新增一個方法,用來設定監聽器
        public void setOnItemClickListener(OnItemClickListener listener) {
            this.listener = listener;
        }
    
        // ... 其他程式碼 ...
    
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            // ... 綁定資料的程式碼 ...
            holder.itemView.setOnClickListener(v -> {
                if (listener != null) {
                    listener.onItemClick(position);
                }
            });
        }
    }`
    
  2. MainActivity.java 中實現介面並設定監聽器:

    `import android.widget.Toast;
    
    // 讓你的 MainActivity 實現你的介面
    public class MainActivity extends AppCompatActivity implements YourAdapter.OnItemClickListener {
        // ... 其他程式碼 ...
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // ... 初始化 RecyclerView 和 Adapter ...
            yourAdapter.setOnItemClickListener(this);
        }
    
        // 實現介面的方法
        @Override
        public void onItemClick(int position) {
            // 在這裡處理點擊事件
            String clickedItem = yourDataList.get(position);
            Toast.makeText(this, "點擊了: " + clickedItem, Toast.LENGTH_SHORT).show();
        }
    }`

程式碼解釋
- 我們在 Adapter 中定義了一個 interface,這就像是訂立了一個「契約」。
- onBindViewHolder 中,我們為每個項目設定了一個 OnClickListener。當項目被點擊時,它就會呼叫 listener.onItemClick()
- MainActivity 實現了這個「契約」,並在 onCreate 中將自己設定為 listener,這樣當點擊事件發生時,onItemClick() 方法就會被呼叫。

二、顯示多種項目類型

  • 簡單比喻: 這就像是 「在一個箱子裡裝不同的東西」
    • RecyclerView 預設只能處理一種項目佈局。但我們可以透過覆寫 Adapter 的兩個方法,來告訴 RecyclerView:「這個位置的項目,請用這種佈局。」

實作步驟:

  1. YourAdapter.java 中覆寫方法:
    `public class YourAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        // ... 其他程式碼 ...
    
        private static final int TYPE_TEXT = 0; // 第一種項目類型
        private static final int TYPE_IMAGE = 1; // 第二種項目類型
    
        @Override
        public int getItemViewType(int position) {
            // 在這裡判斷這個位置的項目是哪種類型
            if (dataList.get(position).isText()) { // 假設你的資料類別有一個判斷方法
                return TYPE_TEXT;
            } else {
                return TYPE_IMAGE;
            }
        }
    
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            // 根據 viewType 決定要載入哪種佈局
            if (viewType == TYPE_TEXT) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_text, parent, false);
                return new TextViewHolder(view); // 建立對應的 ViewHolder
            } else {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_image, parent, false);
                return new ImageViewHolder(view);
            }
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            // 根據 ViewHolder 的類型來綁定資料
            if (holder instanceof TextViewHolder) {
                // 綁定文字資料
            } else if (holder instanceof ImageViewHolder) {
                // 綁定圖片資料
            }
        }
    }`

程式碼解釋
- getItemViewType():這是最關鍵的方法。它會告訴 RecyclerViewposition 這個位置的項目,屬於哪種類型(TYPE_TEXTTYPE_IMAGE)。
- onCreateViewHolder()RecyclerView 會根據 getItemViewType() 回傳的類型,來呼叫這個方法,並傳入 viewType。我們就可以根據這個 viewType,載入不同的佈局。

今日總結

今天我們學會了 RecyclerView 的兩個進階應用:

  • 如何在 Adapter 中新增 interface 來處理項目點擊事件。
  • 如何使用 getItemViewType()onCreateViewHolder(),讓 RecyclerView 能夠顯示多種不同樣式的項目。

明天見!


上一篇
Day26- 綜合挑戰:打造一個簡單的天氣
下一篇
Day28- 偵探的工具:Logcat 與偵錯技巧
系列文
Android 開發者養成計畫:從程式邏輯到作品集實戰30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言